<template>
  <el-select
      :disabled="disabled"
      :size="size"
      :clearable="clearable"
      :placeholder="placeholder"
      :no-data-text="noDataText"
      :popper-class="popperClass"
      :popper-append-to-body="popperAppendToBody"
      :multiple="multiple"
      value-key="id"
      :value="value"
      @visible-change="handleVisibleChange"
      @remove-tag="handleRemoveTag"
      @clear="handleClear"
      ref="selectRef"
      style="width: 500px"
  >
    <el-option
        v-if="data.length !== 0"
        value=""
        style="display: none"
    ></el-option>

    <template v-if="value">
      <el-option
          v-for="item in optionData"
          :value="item.id"
          :label="item.label"
          style="display: none"
          :key="item.id"
      ></el-option>
    </template>

    <el-tree
        :node-key="valueKey"
        :props="props"
        :data="data"
        :highlight-current="highlightCurrent"
        :default-expand-all="defaultExpandAll"
        :expand-on-click-node="expandOnClickNode"
        :check-on-click-node="checkOnClickNode"
        :auto-expand-parent="autoExpandParent"
        :show-checkbox="showCheckbox"
        :check-strictly="checkStrictly"
        @check="handleCheck"
        @current-change="handleCurrentChange"
        ref="treeRef"
    ></el-tree>
  </el-select>
</template>

<script>
export default {
  name: "TreeSelectMulti",
  componentName: 'TreeSelectMulti',
  model: {
    prop: "value",
    event: "update:value",
  },
  emits: ["update:value", "visible-change", "change"],

  props: {
    value: {
      type: String | Number | Array,
    },
    data: {
      type: Array,
      required: true,
      default: () => [],
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    size: {
      type: "medium" | "small" | "mini",
    },
    clearable: {
      type: Boolean,
      default: false,
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    noDataText: {
      type: String,
      default: "无数据",
    },
    popperClass: {
      type: String,
    },
    popperAppendToBody: {
      type: Boolean,
      default: true,
    },
    // tree
    nodeKey: {
      type: String,
      required: true,
    },
    labelKey: {
      type: String,
      required: true
    },
    valueKey: {
      type: String,
      required: true
    },
    props: {
      type: Object,
      default: () => {
      },
    },
    highlightCurrent: {
      type: Boolean,
      default: false,
    },
    defaultExpandAll: {
      type: Boolean,
      default: false,
    },
    expandOnClickNode: {
      type: Boolean,
      default: false,
    },
    checkOnClickNode: {
      type: Boolean,
      default: false,
    },
    autoExpandParent: {
      type: Boolean,
      default: false,
    },
    checkStrictly: {
      type: Boolean,
      default: false,
    },
  },

  computed: {
    showCheckbox() {
      return this.multiple;
    },
  },

  watch: {
    value(val) {
      if (!this.multiple) {
        this.setCurrentNode(val[this.labelKey]);
      } else {
        this.setMultipleCurrentNode(val);
      }
      if (!val) {
        return;
      }
      this.optionData = this.flatteningTreeData.filter((item) => {
        return val.includes(item[this.valueKey]);
      });
    },

    data(val) {
      this.flatteningTree(val);
    }

  },

  data() {
    return {
      flatteningTreeData: [],
      optionData: []
    };
  },

  methods: {
    /**
     * 扁平化树形结构
     * @param {Array} data
     */
    flatteningTree(data) {
      data.forEach((item) => {
        const children = "children"
        if (item[children] && item[children].length) {
          this.flatteningTree(item[children]);
        } else {
          delete item[children];
        }
        this.flatteningTreeData.push(item);
      });
    },

    handleCheck(data, {checkedKeys, halfCheckedKeys}) {
      if (this.multiple) {
        let val = [...checkedKeys, ...halfCheckedKeys];
        this.$emit("update:value", val);
        this.$emit("change", val);
      }
    },
    handleCurrentChange(data) {
      if (!this.multiple) {
        this.$emit("update:value", data.id);
        // this.$emit("change", data);
        this.$refs.selectRef.blur();
      }
    },

    /**
     * 单选节点选中
     * @param {String} val key
     */
    setCurrentNode(val) {
      this.$nextTick(() => {
        this.$refs.treeRef.setChecked(val);
      });
    },

    /**
     * 多选节点选中
     * @param {Array} data
     */
    setMultipleCurrentNode(data) {
      this.$nextTick(() => {
        this.$refs.treeRef.setCheckedKeys(data, this.checkStrictly);
      });
    },

    handleVisibleChange(visible) {
      if (visible) {
        this.multiple
            ? this.setMultipleCurrentNode(this.value)
            : this.setCurrentNode(this.value);
      }
      this.$emit("visible-change", visible);
    },

    handleRemoveTag(val) {
      val = this.value.filter((item) => item !== val);
      this.$emit("update:value", val);
    },

    handleClear() {
      this.$emit("update:value", undefined);
    }
  },

  created() {
    this.flatteningTree(this.data);
    this.optionData = this.flatteningTreeData;
  }
}
</script>
